package drds.binlog.database_driver.packets.client;

import drds.binlog.common.Authors;
import drds.binlog.database_driver.packets.CommandPacket;
import drds.binlog.database_driver.utils.Bytes;
import drds.common.$;
import drds.common.Author;
import lombok.Getter;
import lombok.Setter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * COM_BINLOG_DUMP
 */
@Author(name = Authors.LI_YANG)
public class BinlogDumpCommandPacket extends CommandPacket
{

    /**
     * BINLOG_DUMP options
     */
    public static final int BINLOG_DUMP_NON_BLOCK = 1;
    public static final int BINLOG_SEND_ANNOTATE_ROWS_EVENT = 2;

    @Setter
    @Getter
    public long binlogPosition;
    @Setter
    @Getter
    public long slaveServerId;
    @Setter
    @Getter
    public String binlogFileName;

    public BinlogDumpCommandPacket()
    {
        setCommand((byte) 0x12);
    }

    public void fromBytes(byte[] bytes)
    {
        // bypass
    }

    /**
     * <pre>
     * Bytes                        Name
     *  -----                        ----
     *  1                            command
     *  n                            arg
     *  --------------------------------------------------------
     *  Bytes                        Name
     *  -----                        ----
     *  4                            binlog position to start at (little endian)
     *  2                            binlog flags (currently not used; always 0)
     *  4                            server_id of the slave (little endian)
     *  n                            binlog file name (optional)
     *
     * </pre>
     */
    public byte[] toBytes() throws IOException
    {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 0. write command number
        byteArrayOutputStream.write(getCommand());
        // 1. write 4 bytes bin-log position to start at
        Bytes.writeUnsigned4IntLittleEndian(byteArrayOutputStream, binlogPosition);
        // 2. write 2 bytes bin-log flags
        int binlog_flags = 0;
        binlog_flags |= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
        byteArrayOutputStream.write(binlog_flags);
        byteArrayOutputStream.write(0x00);
        // 3. write 4 bytes server id of the slave
        Bytes.writeUnsigned4IntLittleEndian(byteArrayOutputStream, this.slaveServerId);
        // 4. write bin-log file name if necessary
        if ($.isNotNullAndNotEmpty(this.binlogFileName))
        {
            byteArrayOutputStream.write(this.binlogFileName.getBytes());
        }
        return byteArrayOutputStream.toByteArray();
    }

}
